package main

import (
	"fmt"
)

// ----- OOP 面向对象编程；结构体是值类型！！！！！------
// 1.结构体的定义和基本使用
// 2.创建结构体的四种方式~
// 3.结构体的值拷贝
// 4.复杂结构体的赋值
func main() {
	//结构体基本使用
	defineStructAndUse()

	// 创建结构体的四种方式~
	fourWays4CreateStruct()

	// 结构体的值拷贝
	copyStruct()

	// 复杂结构体的赋值
	complexStruct()
}

// defineStructAndUse
//
//	@Description:结构体的定义和基本使用
func defineStructAndUse() {
	fmt.Println("-------------结构体的定义和基本使用-------------")
	var cat Cat
	fmt.Printf("%T %v \n", cat, cat) //Name、Color默认空字符串，Age默认0
	cat.Name = "tom"
	cat.Color = "白色"
	cat.Age = 3
	fmt.Println("cat=", cat)
	fmt.Printf("Name=%v Age=%v Color=%v \n", cat.Name, cat.Age, cat.Color)
}

// testMonster01
//
//	@Description: 创建结构体的四种方式
func fourWays4CreateStruct() {
	fmt.Println("-------------创建结构体的四种方式-------------")
	//一、定义变量+赋值
	var monster1 Monster
	monster1.Name = "牛魔王"
	monster1.Age = 2000
	monster1.Skill = "牛魔拳"
	fmt.Printf("Name=%v Age=%v Skill=%v \n", monster1.Name, monster1.Age, monster1.Skill)

	//二、直接赋值
	var monster2 Monster = Monster{"铁扇公主", 1001, "铁扇"}
	//var monster21 Monster = Monster{Name: "黄眉大王",Age: 888,Skill: "吹牛"}
	fmt.Printf("Name=%v Age=%v Skill=%v \n", monster2.Name, monster2.Age, monster2.Skill)

	//三、使用new，返回指针
	var monster3 *Monster = new(Monster)
	(*monster3).Name = "孙悟空"
	(*monster3).Age = 999
	(*monster3).Skill = "金箍棒"
	fmt.Printf("Name=%v Age=%v Skill=%v \n", (*monster3).Name, (*monster3).Age, (*monster3).Skill)

	//使用& 返回指针
	var monster4 *Monster = &Monster{}
	(*monster4).Name = "小篆风"
	(*monster4).Age = 200
	(*monster4).Skill = "吹风"
	fmt.Printf("Name=%v Age=%v Skill=%v \n", (*monster4).Name, (*monster4).Age, (*monster4).Skill)
	var monster41 *Monster = &Monster{
		Name:  "青牛精",
		Age:   709,
		Skill: "金刚圈",
	}
	fmt.Printf("Name=%v Age=%v Skill=%v \n", (*monster41).Name, (*monster41).Age, (*monster41).Skill)
}

// testPerson01
//
//	@Description: 复杂结构体的赋值
func complexStruct() {
	fmt.Println("-------------复杂结构体的赋值-------------")
	var person Person
	person.Name = "tom"
	person.Age = 10
	person.Scores = [5]float64{99.0, 95.0, 100.0, 98.0, 97.0}  //数组
	person.Slice = []int{1, 2, 3}                              //切片
	person.Map = map[string]string{"name": "tom", "age": "10"} //map
	person.Ptr = &person.Age                                   //指针
	person.Mo = Monster{"牛魔王", 120, "芭蕉扇"}                     //结构体
	person.MoArray = [2]Monster{
		{"牛魔王1", 120, "芭蕉扇1"},
		{"牛魔王2", 120, "芭蕉扇2"},
	} //结构体数组
	person.MoSlice = []Monster{
		{"牛魔王1", 120, "芭蕉扇1"},
	} //结构体切片

	//结构体map
	person.MoMap = map[string]Monster{
		"Q1": {
			Name:  "铁山公主1",
			Age:   1001,
			Skill: "扇子",
		},
		"Q2": {
			Name:  "铁扇公主2",
			Age:   1001,
			Skill: "扇子",
		},
	}

	fmt.Println("Name=", person.Name)
	fmt.Println("Age=", person.Age)
	fmt.Println("Scores=", person.Scores)
	fmt.Println("Slice=", person.Slice)
	fmt.Println("Map=", person.Map)
	fmt.Println("Ptr=", person.Ptr)
	fmt.Println("Mo=", person.Mo)
	fmt.Println("MoArray=", person.MoArray)
	fmt.Println("MoSlice=", person.MoSlice)
	fmt.Println("MoMap=", person.MoMap)
}

// testMonster02
//
//	@Description: 结构体的值拷贝
func copyStruct() {
	fmt.Println("-------------结构体的值拷贝-------------")
	var monster1 Monster = Monster{
		Name:  "牛魔王",
		Age:   999,
		Skill: "大刀",
	}
	//值拷贝
	monster2 := monster1

	//值拷贝
	fmt.Printf("%v %p \n", monster1, &monster1) //{牛魔王 999 大刀} 0xc00001e210
	fmt.Printf("%v %p \n", monster2, &monster2) //{牛魔王 999 大刀} 0xc00001e240
	monster2.Name = "master2-HH"
	fmt.Printf("%v %p \n", monster1, &monster1) //{牛魔王 999 大刀} 0xc00001e210
	fmt.Printf("%v %p \n", monster2, &monster2) //{master2-HH 999 大刀} 0xc00001e240
}

// Cat
// @Description: CAT
type Cat struct {
	Name  string
	Age   int
	Color string
}

// Person
// @Description: 复杂结构体
type Person struct {
	Name    string             //string
	Age     int                //int
	Scores  [5]float64         //数组
	Ptr     *int               //ptr
	Slice   []int              // 切片
	Map     map[string]string  //map
	Mo      Monster            //结构体
	MoArray [2]Monster         //结构体数组
	MoSlice []Monster          //结构体切片
	MoMap   map[string]Monster //结构体map
}

// Monster
// @Description: 结构体的定义
type Monster struct {
	Name  string
	Age   int
	Skill string
}
